package com.cloudeasy.server.service;

import com.cloudeasy.server.po.Role;
import com.cloudeasy.server.po.UserRole;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 自定义用户详细信息服务
 */
@Service
public class CustomUserDetailServiceImpl implements UserDetailsService {
    private final UserService userService;

    private final UserRoleService userRoleService;

    private final RoleService roleService;

    public CustomUserDetailServiceImpl(UserService userService, UserRoleService userRoleService, RoleService roleService) {
        this.userService = userService;
        this.userRoleService = userRoleService;
        this.roleService = roleService;
    }

    /**
     * 获取用户信息，构建{@link User}
     *
     * @param username 用户名（账号）
     * @return {@link UserDetails}
     * @throws UsernameNotFoundException 用户名（账号）没有找到异常
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        com.cloudeasy.server.po.User user = userService.getByAccount(username);
        if (user == null) {
            throw new UsernameNotFoundException(username);
        }
        List<UserRole> userRoles = userRoleService.getEnableListByUserId(user.getId());
        List<String> roleIds = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList());
        List<Role> roles = roleService.getEnableListByIds(roleIds);

        List<SimpleGrantedAuthority> grantedAuthorities = roles.stream()
                .filter(Role::getEnable)
                .map(role -> new SimpleGrantedAuthority(role.getName()))
                .collect(Collectors.toList());
        return new User(user.getAccount(), user.getPassword(),
                true, true, true, user.getUnlocked(),
                grantedAuthorities);
    }
}
